//promise 基础功能的实现

const PENDING = "pending";
const FULFILLED = 'fulfilled';
const REJECTED = "rejected";

class PromiseMon {
    //定义promise中的状态，默认状态为pending
    status = PENDING;
    //定义成功和失败时的值，默认都是未定义
    value = undefined;
    reason = undefined;

    //定义两个变量，来存放成功和失败时的回调函数
    successCB = [];
    failCB = [];

    //cb即callback，是传给promise的回调函数
    constructor(cb){
        //cb这个函数回调会被立即执行，作用是判断状态是否应该进行更改
        cb(this.resolve, this.reject)
    }

    //使用箭头函数的原因：箭头函数可以减少this指向造成的问题，将其绑定在promise的实例对象
    // resolve 回调函数
    resolve = (value) => {
        //只有当状态为pending时才能修改
        if(this.status !== PENDING){
            return
        } else {
            this.status = FULFILLED
            //将成功的值赋予给value
            this.value = value

            while(this.successCB.length){
                this.successCB.shift(this.value)
            }
        }
    }

    //reject回调函数
    reject = (reason) => {
        //只有当状态为pending时才能修改
        if(this.status !== PENDING){
            return
        } else {
            this.status = REJECTED
            //将失败的原因赋给reason
            this.reason = reason

            while(this.failCB.length){
                this.failCB.shift(this.reason)
            }
        }
    }

    //then要接收两个回调函数，sucessCB 这个回调函数在状态为fulfilled时使用，而failCB这个回调函数在状态为rejected时进行使用
    then(successCB, failCB){
        //新建一个promise对象，来给下一个then使用，三种状态
        //1、promise对象执行成功，调用reslove
        //2、promise对象执行失败，调用reject
        //3、promise对象还未执行，将回调函数推入准备好的数组中

        const thenablePromise = new PromiseMon((resolve, reject) => {
            if(this.status === FULFILLED){
                const thenableValue = successCB(this.value)

                //判断返回的值是否是Promise对象
                resolvePromise(thenableValue, resolve, reject)
            } else if(this.status === REJECTED){
                const thenableReason = failCB(this.reason)

                //判断返回的值是否是Promise对象
                resolvePromise(thenableReason, resolve, reject)
            } else {
                //通过箭头函数的方式将回调函数的值存放进数组中
                this.successCB.push(()=>{
                    const thenableValue = successCB(this.value)
                    resolvePromise(thenableValue, resolve, reject)
                })

                this.failCB.push(()=>{
                    const thenableReason = failCB(this.reason)
                    resolvePromise(thenableReason, resolve, reject)
                })
            }
        })

        return thenablePromise
    }
}

const resolvePromise = (thenablePromise, resolve, reject) => {
    //判断是否是一个promise对象
    if(thenablePromise instanceof PromiseMon){
        thenablePromise.then(resolve,reject)   
    } else {
        //如果不是promise对象，则直接返回值
        resolve(thenablePromise)
    }
}


let axios = require('axios')  //注意： node环境不支持import

let data = new PromiseMon((resolve,reject)=>{
    axios.get('https://baijiahao.baidu.com/s?id=1727544623666200953&wfr=spider&for=pc').then(res=>{
        console.log('777777',res)
        resolve(res)
    }).catch(err=>{
       reject(err)
    })
})

console.log(data)